package com.oneday.ashop.webgate.book;

import com.oneday.ashop.core.base.util.CollectionUtil;
import com.oneday.ashop.core.base.util.CommonUtil;
import com.oneday.ashop.core.base.util.DateUtil;
import com.oneday.ashop.core.base.util.StringUtil;
import com.oneday.ashop.core.entity.CommonConstant;
import com.oneday.ashop.core.entity.Page;
import com.oneday.ashop.core.entity.User;
import com.oneday.ashop.core.entity.book.*;
import com.oneday.ashop.webgate.base.file.BaseFileOperate;
import com.oneday.ashop.webgate.base.ftp.SFtpUtil;
import com.oneday.ashop.webgate.user.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;

/**
 * 读书service层
 * User:bob.yang
 * Date 2015/8/14 0014
 */
@Service
public class BookService {

    @Autowired
    private BookDao bookDao;
    @Autowired
    private UserDao userDao;

    /**
     * 上传电子书
     * @param
     * @return
     */
    public int upload(String bookName, String bookAuthor, String bookPublishDate,
                      MultipartFile bookImage, String picName, String strImage, MultipartFile bookFile,
                      String bookIntroduction, User user) {
        // 文件类型验证
        if (!this.checkImageType(bookImage)) {
            // 图片格式不正确
            return 11;
        }
        if (!this.checkBookType(bookFile)) {
            // 电子书格式不正确
            return 12;
        }
        // 验证上传文件大小
        if (!this.checkSize(bookImage.getSize(), CommonConstant.IMAGE_PATH)) {
            // 图片大小超过限制
            return 1;
        } else if (!this.checkSize(bookFile.getSize(), CommonConstant.FILE_PATH)) {
            // 文件大小超过限制
            return 2;
        } else {
            String imageName = this.getNewName(picName, CommonUtil.createUUID());
            String fileName = this.getNewName(bookFile.getOriginalFilename(), bookAuthor);

            try {
                // 获取图片文件
                MultipartFile imageFile = (MultipartFile)this.getImageFile(strImage, imageName);

                Book book = new Book();
                book.setName(bookName);
                book.setAuthor(bookAuthor);
                book.setPublishDate(bookPublishDate.toString());
                book.setImage(imageName);
                book.setIntroduction(bookIntroduction);
                book.setBookFile(fileName);
                book.setAddTime(DateUtil.getCurrentDateTime());
                book.setUploadUser(user.getName());
                book.setSearchTimes(0L);
                book.setComments(new ArrayList<Integer>());
                book.setCheckStatus(0);
                book.setConmentNum(0);
                bookDao.addBook(book);
                SFtpUtil.upload(imageFile, imageName, CommonConstant.IMAGE_PATH);
                SFtpUtil.upload(bookFile, fileName, CommonConstant.FILE_PATH);
                return 0;
            } catch (Exception e){
                return 13;
            } finally {
                String path = "C:/" + imageName;
                File f = new File(path);  // 输入要删除的文件位置
                if(f.exists()) {
                    f.delete();
                }
            }

        }
    }

    /**
     * 上传封面
     * @param icon
     * @return
     */
    public String uploadImg(MultipartFile icon) {
        String imageName = null;
        try {
            imageName = BaseFileOperate.imageUpload(icon);
        } catch (IOException e) {
            throw new RuntimeException();
        }
        return imageName;
    }

    /**
     * 截取图片
     * @param imgUrl 图片路径
     * @param x 横坐标
     * @param y 纵坐标
     * @param width 宽
     * @param height 高
     */
    public void cropImg(String imgUrl, int x, int y, int width, int height) {
        int index = imgUrl.lastIndexOf('.');
        String imgType = imgUrl.substring(index + 1);
        String newImgUrl;
        try {
            newImgUrl = BaseFileOperate.cropImg(imgUrl, x, y, width, height, imgType);
        } catch (MalformedURLException e) {
            throw new RuntimeException();
        }
    }

    /**
     * base64字符串转换成图片
     * @param imgStr
     * @param imageName
     * @return
     */
    private File getImageFile(String imgStr, String imageName) {
        imgStr = imgStr.split(";base64,")[1];
        String imagePath = "C:";
        File targetFile = new File(imagePath, imageName);

        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            // 生成jpeg图片
            //String imgFilePath = "d:/test22.png";// 新生成的图片
            OutputStream out = new FileOutputStream(targetFile);
            out.write(b);
            out.flush();
            out.close();
            return targetFile;
        } catch (Exception e) {
            System.out.println(e.toString());
            return null;
        }
    }

    /**
     * 搜索热门书籍
     * @return
     */
    public List<Book> queryHotBooks() {
        List<Book> hotBookList = bookDao.queryHotBooks();
        if (!hotBookList.isEmpty() && hotBookList.size() >= CommonConstant.SHOW_HOT_BOOK_NUM) {
            return hotBookList.subList(0, CommonConstant.SHOW_HOT_BOOK_NUM);
        } else {
            return hotBookList;
        }
    }

    /**
     * 搜索推荐书籍
     * @return
     */
    public List<Book> queryRecommendBooks() {
        List<Book> recBookList = bookDao.queryRecommendBooks();
        if (!recBookList.isEmpty() && recBookList.size() >= CommonConstant.SHOW_REC_BOOK_NUM) {
            return recBookList.subList(0, CommonConstant.SHOW_REC_BOOK_NUM);
        } else {
            return recBookList;
        }
    }

    /**
     * 搜索热门评论
     * @return
     */
    public List<Comment> queryHotComments() {
        List<Comment> commentList = bookDao.queryHotComments();
        List<Book> bookList = bookDao.queryAllBooks();
        if (!commentList.isEmpty() && commentList.size() >= CommonConstant.SHOW_HOT_COMMENTS_NUM) {
            commentList = commentList.subList(0, CommonConstant.SHOW_HOT_COMMENTS_NUM);
        }

        // 遍历bookList获取评论书籍的封面
        for (int i = 0;i < commentList.size();i++) {
            for (Book book : bookList) {
                if (book.getId().equals(commentList.get(i).getBookID())) {
                    commentList.get(i).setImage(book.getImage());
                    commentList.get(i).setBookName(book.getName());
                }
            }
        }
        return commentList;
    }

    /**
     * 发表心情
     * @param content
     */
    public void publishMood(Integer uid, String imgUrls, String content) {
        Mood mood = new Mood();
        mood.setUid(uid);
        mood.setContent(content);
        mood.setAddTime(new Date());
        mood.setImages(new ArrayList<String>());
        String[]  images = imgUrls.split("\\|");
        for(String url : images) {
            if(!StringUtil.isEmpty(url)) {
                mood.getImages().add(url);
            }
        }
        bookDao.addMood(mood);
    }

    /**
     * 查找心情
     * @param uid
     * @return
     */
    public void findMoodPage(Integer uid, Page<Mood> page) {
        page.getFilter().put("uid", uid);
        bookDao.findMoodPage(page);
        Set<Integer> uids = new TreeSet<>();
        for(Mood mood : page.getResult()) {
            uids.add(mood.getUid());
        }
        //查找所有发布心情的用户
        List<User> users = bookDao.findUsers(uids, "_id", "name", "imgUrl");
        Map<Integer, User> userMap = CollectionUtil.buildMap(users, Integer.class, User.class, "id");
        //设置用户姓名，并且判断如果该心情是日志心情，则查出对应日志并且 返回
        for(Mood mood : page.getResult()) {
            mood.setUserName(userMap.get(mood.getUid()).getName());
            if(Mood.TYPE_BLOG.equals(mood.getType())) {
                Blog blog = bookDao.findBlogById(mood.getBid(), "title", "content");
                if(blog.getContent().length() > 100) {
                    String content = blog.getContent();
                    content = content.substring(0, 100);
                    blog.setContent(content);
                }
                mood.setBlog(blog);
            }
            mood.setImgUrl(userMap.get(mood.getUid()).getImgUrl());
        }
        //查找用户评论
        if(page.getResult().size() != 0) {
            List<Mood> moods = page.getResult();
            for(Mood mood : moods) {
                List<Comment> comments = bookDao.findComment(mood.getId());
                mood.setComments(comments);
                if(mood.getPraiseUids() != null) {
                    mood.setPraiseNum(mood.getPraiseUids().size());
                }
            }
        }
    }

    /**
     * 验证上传文件大小
     * @param size
     * @param type
     * @return
     */
    public boolean checkSize(long size, Integer type) {
        if (CommonConstant.IMAGE_PATH == type && CommonConstant.IMAGE_MAX_SIZE >= size) {
            return true;
        } else if (CommonConstant.FILE_PATH == type && CommonConstant.FILE_MAX_SIZE >= size){
            return true;
        } else {
            return false;
        }
    }

    /**
     * 验证图片格式
     * @param bookImage
     * @return
     */
    public boolean checkImageType(MultipartFile bookImage) {
        String imageName = bookImage.getOriginalFilename();
        String type = (imageName.substring(imageName.lastIndexOf(".") + 1, imageName.length())).toLowerCase();
        // 获取允许图片格式
        List<String> imageTypeList = CollectionUtil.initImageType();
        for(String imageType : imageTypeList) {
            if (imageType.equals(type)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 验证电子书格式
     * @param bookFile
     * @return
     */
    public boolean checkBookType(MultipartFile bookFile) {
        String bookName = bookFile.getOriginalFilename();
        String type = (bookName.substring(bookName.lastIndexOf(".") + 1, bookName.length())).toLowerCase();
        List<String> bookTypeList = CollectionUtil.initBookType();
        for(String bookType : bookTypeList) {
            if (bookType.equals(type)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 获取唯一名称
     * @param name
     * @param str
     * @return
     */
    public String getNewName(String name, String str) {
        String newName = name.substring(0, name.lastIndexOf(".")) + "-" + str
                + name.substring(name.lastIndexOf("."), name.length());
        return newName;
    }

    /**
     * 心情回复
     * @param uid
     * @param mid
     * @param content
     */
    public void moodComment(Integer uid, Integer mid, String content) {
        Comment comment = new Comment();
        comment.setAddTime(new Date());
        comment.setContent(content);
        comment.setMid(mid);
        comment.setUid(uid);
        User user = userDao.findUser(uid, "name");
        comment.setUserName(user.getName());
        bookDao.addComment(comment);
    }

    /**
     * 根据心情号查询回复
     * @param mid
     * @return
     */
    public List<Comment> findComment(Integer mid) {
        return bookDao.findComment(mid);
    }

    /**
     * 心情点赞
     * @param uid
     * @param mid
     */
    public void moodPraise(Integer uid, Integer mid) {
        Mood mood = bookDao.findMoodById(mid);
        if(mood.getPraiseUids() == null) {
            mood.setPraiseUids(new ArrayList<Integer>());
        }
        if(mood.getPraiseUids().contains(uid)) {
           mood.getPraiseUids().remove(uid);
        }else {
            mood.getPraiseUids().add(uid);
        }
        bookDao.updateMood(mid, mood);
    }

    /**
     * 删除心情 //TODO 该处的删除全都是逻辑删除，本人可以删除自己的心情，如果是别人的心情，直接是不关注了
     * @param uid
     * @param mid
     */
    public void moodDelete(Integer uid, Integer mid) {
        Mood mood = bookDao.findMoodById(mid);
        //判断这个心情是不是本人的
        if(mood.getUid().equals(uid)) {
            bookDao.updateMoodById(mid, Mood.STATUS_DELETED);
        }
    }

    /**
     *写日志
     * @param uid
     * @param title
     * @param content
     * @param blogPrivacy
     * @param couldReply
     */
    public void writeBlog(Integer uid, String title, String content, Integer blogPrivacy, Integer couldReply) {
        Blog blog = new Blog();
        blog.setUid(uid);
        blog.setTitle(title);
        blog.setContent(content);
        blog.setBlogPrivacy(blogPrivacy);
        blog.setCouldReply(couldReply);
        blog.setAddTime(new Date());
        bookDao.addBlog(blog);
        //然后查出新插入的这条数据，其实这里应该涉及到事务，但是木有
        Blog blog1 = bookDao.findBlog(uid, "_id");
        //插入日志之后要新增一条心情
        Mood mood = new Mood();
        mood.setUid(uid);
        mood.setType(Mood.TYPE_BLOG);
        mood.setBid(blog1.getId());
//        mood.setContent();
        mood.setAddTime(blog.getAddTime());
        bookDao.addMood(mood);
    }

    /**
     * 查找日志
     * @param bid
     * @return
     */
    public Blog findBlog(Integer bid) {
        Blog blog = bookDao.findBlogById(bid);
        //换行
        blog.setContent(blog.getContent().replace("\n", "<br><br>"));
        User user = userDao.findUser(blog.getUid(), "name");
        blog.setUserName(user.getName());
        return blog;
    }
}
